using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using FuncWorks.Xna.Input;
using FuncWorks.Xna.UI;

namespace ButtonGuideDemo
{
	/// <summary>
	/// This is the main type for your game
	/// </summary>
	public class Game1 : Microsoft.Xna.Framework.Game
	{
		GraphicsDeviceManager graphics;
		SpriteBatch spriteBatch;
		ButtonGuide buttonGuide;
		List<Controller> controllers;

		public Game1()
		{
			graphics = new GraphicsDeviceManager(this);
			Content.RootDirectory = "Content";
		}

		/// <summary>
		/// Allows the game to perform any initialization it needs to before starting to run.
		/// This is where it can query for any required services and load any non-graphic
		/// related content.  Calling base.Initialize will enumerate through any components
		/// and initialize them as well.
		/// </summary>
		protected override void Initialize()
		{
			controllers = new List<Controller>();
			controllers.Add(new Controller(PlayerIndex.One));
			controllers.Add(new Controller(PlayerIndex.Two));
			controllers.Add(new Controller(PlayerIndex.Three));
			controllers.Add(new Controller(PlayerIndex.Four));

			base.Initialize();
		}

		/// <summary>
		/// LoadContent will be called once per game and is the place to load
		/// all of your content.
		/// </summary>
		protected override void LoadContent()
		{
			// Create a new SpriteBatch, which can be used to draw textures.
			spriteBatch = new SpriteBatch(GraphicsDevice);

			buttonGuide = new ButtonGuide(
				new TextStyle(Content.Load<SpriteFont>("SpriteFont1"), Color.White, Color.Black, 2, AnchorPoint.BottomRight),
				AnchorPoint.BottomRight, 8, graphics
				);
			buttonGuide.AddPanel("A", Content.Load<Texture2D>("xboxControllerButtonA"), "Button A", true);
			buttonGuide.AddPanel("B", Content.Load<Texture2D>("xboxControllerButtonB"), "Button B", true);
			buttonGuide.AddPanel("X", Content.Load<Texture2D>("xboxControllerButtonX"), "Button X", true);
			buttonGuide.AddPanel("Y", Content.Load<Texture2D>("xboxControllerButtonY"), "Button Y", true);
			buttonGuide.AddPanel("0", null, "No Icon", true);

			// Must call initialize before drawing
			buttonGuide.Initialize();
		}


		/// <summary>
		/// Allows the game to run logic such as updating the world,
		/// checking for collisions, gathering input, and playing audio.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
		protected override void Update(GameTime gameTime)
		{
			GamePadState gamePadState = GamePad.GetState(PlayerIndex.One);
			KeyboardState keyboardState = Keyboard.GetState();

			if (gamePadState.IsButtonDown(Buttons.Back) || keyboardState.IsKeyDown(Keys.Escape)) { Exit(); }

			// Show/hide button guide panels when the user presses a button
			foreach (Controller c in controllers)
			{
				c.Update(gameTime);

				ButtonGuidePanel panel = null;

				if (c.ButtonReleased[Buttons.A]) { panel = (from p in buttonGuide.Panels where p.Id == "A" select p).First<ButtonGuidePanel>(); }
				else if (c.ButtonReleased[Buttons.B]) { panel = (from p in buttonGuide.Panels where p.Id == "B" select p).First<ButtonGuidePanel>(); }
				else if (c.ButtonReleased[Buttons.X]) { panel = (from p in buttonGuide.Panels where p.Id == "X" select p).First<ButtonGuidePanel>(); }
				else if (c.ButtonReleased[Buttons.Y]) { panel = (from p in buttonGuide.Panels where p.Id == "Y" select p).First<ButtonGuidePanel>(); }

				if (panel != null) { panel.Visible = !panel.Visible; }
			}

			base.Update(gameTime);
		}

		/// <summary>
		/// This is called when the game should draw itself.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
		protected override void Draw(GameTime gameTime)
		{
			GraphicsDevice.Clear(Color.CornflowerBlue);

			spriteBatch.Begin();
			buttonGuide.Draw(spriteBatch);
			spriteBatch.End();

			base.Draw(gameTime);
		}
	}
}
